package com.meng.ioclibrary;

import android.app.Activity;
import android.view.View;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;

/**
 * Created by Administrator on 2017/5/3.
 */

public class ViewFinder {
    private Activity aty;
    private View view;
    public ViewFinder(Activity aty) {
        this.aty = aty;
    }
    public ViewFinder(View view) {
        this.view = view;
    }
    public void initInject(Object object){
        injectContentView();
        injectView(object);
        injectOnClick(object);
    }
    private void injectContentView() {
        if(aty != null){
            ContentView contentView = aty.getClass().getAnnotation(ContentView.class);
            if(contentView != null){
                int value = contentView.value();
                aty.setContentView(value);
            }
        }
    }
    private  void injectView(Object object) {
        Field[] declaredFields = object.getClass().getDeclaredFields();
        //遍历所有的属性，判断是否有View注解
        try {
            for(Field field:declaredFields){
                BindView viewInject = field.getAnnotation(BindView.class);
                if(viewInject != null){
                    int viewId = viewInject.value();
                    View view = findViewById(viewId);
                    field.setAccessible(true);
                    field.set(object,view);
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    /**
     * 点击事件
     * @param object
     */
    private  void injectOnClick(final Object object) {
        Method[] declaredMethods = object.getClass().getDeclaredMethods();
        for(final Method method:declaredMethods){
            OnClick onClick = method.getAnnotation(OnClick.class);
            if(onClick != null){
                int[] viewIds = onClick.value();
                for(int id:viewIds){
                    View view = findViewById(id);
                    DynamicHandler handler = new DynamicHandler(object);
                    handler.addMethod("onClick",method);
                    Object proxy = Proxy.newProxyInstance(
                            View.OnClickListener.class.getClassLoader(),
                            new Class[]{View.OnClickListener.class},
                            handler
                    );
                    try {
                        Method setOnClickListenerMethod = view.getClass().getMethod("setOnClickListener", View.OnClickListener.class);
                        setOnClickListenerMethod.invoke(view,proxy);
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


    private View findViewById(int id){
        return aty == null?view.findViewById(id):aty.findViewById(id);
    }

    public static class DynamicHandler implements InvocationHandler {
        private WeakReference<Object> handlerRef;
        private HashMap<String,Method> methods = new HashMap<>();
        public DynamicHandler(Object handler) {
            handlerRef = new WeakReference<Object>(handler);
        }
        public void addMethod(String methodName,Method method){
            methods.put(methodName,method);
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object obj = handlerRef.get();
            if(obj != null){
                methods.get(method.getName()).invoke(obj,args);
            }
            return null;
        }
    }
}
